package com.example.shiroredisdemo.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

import java.lang.reflect.Method;

/**
 * @Author: Anita
 * @Date: Created in 19:01 2018/1/6
 */
@Configuration
@EnableCaching
@EnableRedisHttpSession
@Slf4j
public class SecondaryRedisConfig extends CachingConfigurerSupport {
    /**
     * 加载属性文件数据
     * @return
     */
    @Bean
    public MyRedisProperties redisProperties(){
        return new MyRedisProperties();
    }

    //TODO jedisPoolConfig

    /**
     * 主键生成器
     * @return
     */
    @Bean
    public KeyGenerator commonKeyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for(Object obj:params){
                    sb.append(obj.toString());
                }
                String key = sb.toString();
                log.info("key:"+key);
                return key;
            }
        };
    }

    @Bean
    public CacheManager cacheManager(@Qualifier("secondaryStringRedisTemplate")RedisTemplate redisTemplate) {
        CacheManager redisCacheManager = new RedisCacheManager(redisTemplate);
        return redisCacheManager;
    }

    @Bean(name = "secondaryStringRedisTemplate")
    public RedisTemplate<String,String> redisTemplate(@Qualifier("secondaryRedisConnectionFactory")RedisConnectionFactory redisConnectionFactory){
        log.info("2.2初始化Redis模版(普通对象)...");
        StringRedisTemplate template = new StringRedisTemplate(redisConnectionFactory);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        om.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);// 创建只输出非Null且非Empty(如List.isEmpty)的属性到Json字符串的Mapper
        GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }

    @Bean(name = "secondaryRedisConnectionFactory")
    public RedisConnectionFactory secondaryRedisConnectionFactory(){
        JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();
        redisConnectionFactory.setDatabase(redisProperties().getSecondaryDatabase());
        redisConnectionFactory.setPassword(redisProperties().getPassword());
        redisConnectionFactory.setHostName(redisProperties().getHost());
        redisConnectionFactory.setTimeout(redisProperties().getTimeout());
        redisConnectionFactory.setPort(redisProperties().getPort());
        redisConnectionFactory.afterPropertiesSet();
        log.info("2.1初始化Redis缓存服务器(普通对象).....");
        return redisConnectionFactory;
    }

    /**
     * 与Session有关设置链接
     * @return
     */
    @Bean
    public RedisOperationsSessionRepository sessionRepository(){
        RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(secondaryRedisConnectionFactory());
        sessionRepository.setDefaultMaxInactiveInterval(redisProperties().getSessionExpire()); //设置session的有效时长
        return sessionRepository;
    }

//    @Bean(name = "redisTemplate")
//    public RedisTemplate<String,Object> sessionRedisTemplate(){
//        RedisTemplate<String,Object> template = new RedisTemplate<>();
//        template.setConnectionFactory(secondaryRedisConnectionFactory());
//        RedisSerializer stringSerializer = new StringRedisSerializer();
//        template.setKeySerializer(stringSerializer);
//        template.setValueSerializer(sessionRedisSerializer());
//        template.setHashKeySerializer(stringSerializer);
//        template.setHashValueSerializer(sessionRedisSerializer());
//        template.afterPropertiesSet();
//        return template;
//    }

//    @Bean
//    @SuppressWarnings("rawtypes")
//    public RedisSerializer sessionRedisSerializer(){
//        return new Jackson2JsonRedisSerializer<Object>(Object.class);
//    }

}
